/*
 * Inspired from the exercise covered at http://chris.agenteight.com/code/.
 * Strip C-style comments from standard input, dumping it to standard output.
 *
 * Extension to C++ style comments is left as an exercise to the student.
 */
#include	<stdio.h>

/*
 * Parsing states.
 * Normal: reading input. Comment: dropping a comment.
 * Constant: inside a string or a character constant.
 * BackSlash: hit a backslash inside a Constant.
 * Slash: we've seen a / in Normal. Star: we've seen a * in Comment.
 */
typedef enum { Normal, Comment, Constant,
	       BackSlash, Slash, Star } PStates;

main(int argc, char **argv)
{
	/* constChar is the character that started (and thus will end)
	   the string or character constant we're reading through in
	   Constant. */
	int	c, constChar;
	PStates	state;

	state = Normal;
	while ((c = getchar()) != EOF) {
		switch (state) {
		    case BackSlash:
			putchar(c);
			state = Constant;
			break;
		    case Constant:
			putchar(c);
			if (c == constChar)
				state = Normal;
			else if (c == '\\')
				state = BackSlash;
			break;
		    case Slash:
			/* We have seen a valid slash; look for * to
			   go into comment mode. */
			if (c == '*') {
				state = Comment;
			} else {
				/* We swallowed the / earlier, so we
				   must now re-emit it. */
				putchar('/'); putchar(c);
				state = Normal;
			}
			break;
		    case Comment:
			/* All we care about is the '*' that starts
			   a potential exit from comment */
			if (c == '*')
				state = Star;
			break;
		    case Star:
			state = (c == '/') ? Normal : Comment;
			break;
		    case Normal:
			if (c != '/')
				putchar(c);
			if (c == '"' || c == '\'') {
				constChar = c;
				state = Constant;
			} else if (c == '/')
				state = Slash;
			break;
		}
	}
	/*
	 * At this point we could emit a message if we are not in state
	 * Normal, to tell the user that his C source file has a syntax
	 * error.
	 */
}
